/**
 *
 * Copyright 2009 Bill Garrett (memesis@gmail.com)
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use
 * this file except in compliance with the License.  You may obtain a copy of the
 * License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed
 * under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific
 * language governing permissions and limitations under the License. 
 */
package org.memesis.pandorasbook;

import java.awt.BorderLayout;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.xml.parsers.ParserConfigurationException;

import org.memesis.pandorasbook.actions.FocusWindowAction;
import org.memesis.pandorasbook.actions.NewWindowAction;
import org.memesis.pandorasbook.actions.QuitAction;
import org.memesis.pandorasbook.util.ExceptionHandler;
import org.xml.sax.SAXException;

/**
 * This class manages the desktop pane for the application.
 * It is responsible for creating new frames.
 * 
 * @author garrett
 */
public class PandoraDesktop {
	private JFrame topLevelWindow;
	private PandoraDesktopPane desktop;
	private PandoraInternalFrameListener listener;
	private JMenu windowsMenu;

	public PandoraDesktop() {
		listener = new PandoraInternalFrameListener(this);
		initializeWindow();
	}
	
	public void openFrame(PandoraApplet applet) {
		PandoraAppletFrame f = new PandoraAppletFrame(applet);
		f.addInternalFrameListener(listener);
		desktop.add(f);
		f.setVisible(true);
	}
	
	// TODO: regenerate windows whose titles have changed
	public void regenerateWindowsMenu() {
		windowsMenu.removeAll();
		for(PandoraAppletFrame frame : listener.getFrames()) {
			windowsMenu.add(new FocusWindowAction(frame));
		}
	}
	
	/**
	 * Set up the window being used by the desktop
	 */
	private void initializeWindow() {
		// Try to look like the host OS whenever possible
		String systemLaf = UIManager.getSystemLookAndFeelClassName();
		if(systemLaf != null) {
			try {
				UIManager.setLookAndFeel(systemLaf);
			} catch (ClassNotFoundException e) {
				ExceptionHandler.reportException(e);
			} catch (InstantiationException e) {
				ExceptionHandler.reportException(e);
			} catch (IllegalAccessException e) {
				ExceptionHandler.reportException(e);
			} catch (UnsupportedLookAndFeelException e) {
				ExceptionHandler.reportException(e);
			}
		}
		
		topLevelWindow = new JFrame();

		topLevelWindow.setTitle("Pandora's Book");
		topLevelWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		topLevelWindow.setLayout(new BorderLayout());
		topLevelWindow.setSize(800, 600);
		
		JMenuBar menubar = createMenuBar();
		topLevelWindow.setJMenuBar(menubar);
		
		desktop = new PandoraDesktopPane();
		topLevelWindow.add(desktop, BorderLayout.CENTER);

		topLevelWindow.setVisible(true);
	}
	
	private JMenuBar createMenuBar() {
		JMenuBar bar = new JMenuBar();
		JMenu menu;
		
		bar.add(menu = new JMenu("File"));
		menu.add(new NewWindowAction(this));
		menu.add(new QuitAction());
		
		// This menu is automatically regenerated by the window listener
		bar.add(windowsMenu = new JMenu("Windows"));
		
		return bar;
	}

	public PandoraApplet runApplet(String targetUrl, Map<String, String> newProps) throws MalformedURLException {
		PandoraApplet newApp = null;

		try {
			URL finalUrl;
			if(null != newProps && newProps.containsKey("pandorasbook-applet-url"))
			{
				finalUrl = new URL(new URL(newProps.get("pandorasbook-applet-url")), targetUrl);
			} else {
				finalUrl = new URL(targetUrl);
			}
			newApp = PandoraAppletFactory.createApplet(finalUrl, this);
			if(null != newProps) {
				newApp.getProperties().putAll(newProps);
			}
			openFrame(newApp);
		} catch (ParserConfigurationException e) {
			ExceptionHandler.reportException(e);
		} catch (SAXException e) {
			ExceptionHandler.reportException(e);
		} catch (IOException e) {
			ExceptionHandler.reportException(e);
		} catch (ClassNotFoundException e) {
			ExceptionHandler.reportException(e);
		} catch (InstantiationException e) {
			ExceptionHandler.reportException(e);
		} catch (IllegalAccessException e) {
			ExceptionHandler.reportException(e);
		}
		
		return newApp;	
	}
}
